package com.hwadee.property.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hwadee.property.dto.ParkingUsePersonal;
import com.hwadee.property.mapper.ParkingUseMapper;
import com.hwadee.property.pojo.Parking;
import com.hwadee.property.pojo.ParkingUse;
import com.hwadee.property.service.*;
import com.hwadee.property.dto.PageResult;
import com.hwadee.property.util.ErrorCodes;
import com.hwadee.property.util.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 车位使用服务实现类
 */
@Service
public class ParkingUseServiceImpl extends ServiceImpl<ParkingUseMapper, ParkingUse> implements IParkingUseService {

    @Autowired
    private ParkingUseMapper parkingUseMapper;

    @Autowired
    private IChargeItemService chargeItemService;

    @Autowired
    private IParkingService parkingService;

    @Autowired
    private IUserService userService;

    @Autowired
    private ICommunityService communityService;

    @Override
    public PageResult<ParkingUse> getPage(int current, int size, Long userId, String carNumber, Long parkingId, Long communityId, String useType, Date startTime, Date endTime) {
        // 校验输入参数合法性
        if (current <= 0) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "当前页码必须大于0");
        }
        if (size <= 0) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "每页大小必须大于0");
        }

        // 确保 current 至少为 1
        current = Math.max(current, 1);
        size = Math.max(size, 1);

        // 计算 offset
        int offset = (current - 1) * size;

        // 查询总记录数
        int total = parkingUseMapper.countParkingUses(userId, carNumber, parkingId, useType, startTime, endTime);

        // 只有当 total > 0 时才查询数据
        List<ParkingUse> records = (total > 0) ?
                parkingUseMapper.getParkingUses(userId, carNumber, parkingId, useType, startTime, endTime, size, offset)
                : Collections.emptyList();

        if (communityId != null){
            List<ParkingUse> results = new ArrayList<>();
            total = 0;
            for (ParkingUse i : records){
                if (parkingService.getById(i.getParkingId()).getCommunityId().equals(communityId)){
                    results.add(i);
                    total++;
                }
            }
            return new PageResult<>(total, current, size, results);
        }

        // 返回分页结果
        return new PageResult<>(total, current, size, records);
    }

    @Override
    public List<ParkingUsePersonal> getByOwner(Long userId) {
        // 校验业主ID
        if (userId == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "业主ID不能为空");
        }
        List<ParkingUse> parkingUses = this.list(new LambdaQueryWrapper<ParkingUse>().eq(ParkingUse::getUserId, userId));
        List<ParkingUsePersonal> parkingUsePersonals = new ArrayList<>();

        for (ParkingUse i : parkingUses){
            ParkingUsePersonal parkingUsePersonal = new ParkingUsePersonal();
            parkingUsePersonal.setUserName(userService.getById(i.getUserId()).getName());
            Parking parking = parkingService.getById(i.getParkingId());
            parkingUsePersonal.setParkingName(communityService.getById(parking.getCommunityId()).getCommunityName() + "小区" +
                    parking.getLocation());
            parkingUsePersonal.setCarNumber(i.getCarNumber());
            parkingUsePersonal.setTotalFee(i.getTotalFee());
            parkingUsePersonal.setStartTime(i.getStartTime());
            parkingUsePersonal.setEndTime(i.getEndTime());
            parkingUsePersonal.setUseType(i.getUseType());
            parkingUsePersonals.add(parkingUsePersonal);
        }
        return parkingUsePersonals;
    }

    @Override
    public Double calculateTotalFee(String useType, Long communityID) {
        // 检查小区ID是否为空
        if (communityID == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "小区ID不能为空");
        }

        // 获取小区的停车费用单价
        Double unitPrice = chargeItemService.getUnitFeeByCommunityID(communityID, "停车费").getAmount();
        if (unitPrice == null) {
            throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "小区ID对应的停车费用单价不存在");
        }

        // 定义费用计算的常量
        final double PURCHASE_MULTIPLIER = 10 * 12; // 购买：10年，每年12个月
        final double YEAR_RENT_MULTIPLIER = 11;     // 年租：11个月
        final double MONTH_RENT_MULTIPLIER = 1;     // 月租：1个月
        final double TEMPORARY_MULTIPLIER = 0.4;    // 临时：0.4倍单价

        // 根据使用类型计算总费用
        switch (useType) {
            case "购买":
                return unitPrice * PURCHASE_MULTIPLIER;
            case "年租":
                return unitPrice * YEAR_RENT_MULTIPLIER;
            case "月租":
                return unitPrice * MONTH_RENT_MULTIPLIER;
            case "临时":
                return unitPrice * TEMPORARY_MULTIPLIER;
            default:
                // 如果使用类型未知，抛出异常
                throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "未知的使用类型: " + useType);
        }
    }

    @Override
    public Date getEndUseTime(Date startTime, String useType) {
        // 根据使用类型计算总时长
        long durationInMillis = 0; // 时长以毫秒为单位
        switch (useType) {
            case "购买":
                durationInMillis = 100L * 365 * 24 * 60 * 60 * 1000; // 100年
                break;
            case "年租":
                durationInMillis = 365L * 24 * 60 * 60 * 1000; // 1年
                break;
            case "月租":
                durationInMillis = 30L * 24 * 60 * 60 * 1000; // 1月（假设每月30天）
                break;
            case "临时":
                durationInMillis = 5L * 24 * 60 * 60 * 1000; // 5天
                break;
            default:
                // 如果使用类型未知，抛出异常
                throw new BusinessException(ErrorCodes.INVALID_PARAMETER, "未知的使用类型: " + useType);
        }

        // 计算结束时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.MILLISECOND, (int) durationInMillis); // 添加时长
        return calendar.getTime();
    }

}
